package com.bus.core.manager.impl;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.mail.MessagingException;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bus.common.email.EmailSender;
import com.bus.common.email.MessageTemplate;
import com.bus.common.page.Pagination;
import com.bus.core.dao.BusUserDao;
import com.bus.core.dao.BusUserEntityDao;
import com.bus.core.entity.BusUser;
import com.bus.core.entity.BusUserExt;
import com.bus.core.entity.UnifiedUser;
import com.bus.core.manager.BusUserExtMng;
import com.bus.core.manager.BusUserMng;
import com.bus.core.manager.BusUserSiteMng;
import com.bus.core.manager.UnifiedUserMng;

@Service
@Transactional
public class BusUserMngImpl implements BusUserMng {
	@Transactional(readOnly = true)
	public Pagination getPage(String username, String email, Integer siteId,
			Integer groupId, Integer statu, Boolean admin, Integer rank,
			String realName,Integer roleId,Boolean allChannel,
			Boolean allControlChannel,int pageNo,
			int pageSize) {
		Pagination page = entityDao.getPage(username, email, siteId, groupId,
				statu, admin, rank,realName,roleId,allChannel, 
				allControlChannel,pageNo,pageSize);
		return page;
	}
	
	@Transactional(readOnly = true)
	public List<BusUser> getList(String username, String email, Integer siteId,
			Integer groupId, Integer statu, Boolean admin, Integer rank) {
		List<BusUser> list = entityDao.getList(username, email, siteId, groupId,
				statu, admin, rank);
		return list;
	}

	@Transactional(readOnly = true)
	public List<BusUser> getAdminList(Integer siteId, Boolean allChannel,
			Integer statu, Integer rank) {
		return entityDao.getAdminList(siteId, allChannel, statu, rank);
	}
	
	@Transactional(readOnly = true)
	public Pagination getAdminsByRoleId(Integer roleId, int pageNo, int pageSize){
		return entityDao.getAdminsByRoleId(roleId, pageNo, pageSize);
	}

	@Transactional(readOnly = true)
	public BusUser findById(Integer id) {
		BusUser entity = entityDao.findById(id);
		return entity;
	}

	@Transactional(readOnly = true)
	public BusUser findByUsername(String username) {
		BusUser entity = dao.findByUsername(username);
		return entity;
	}

	public BusUser registerMember(String username, String email,
			String password, String ip, Integer groupId,Integer grain,boolean uncheck,BusUserExt userExt,Map<String,String>attr){
		UnifiedUser unifiedUser = unifiedUserMng.save(username, email,
				password, ip);
		BusUser user = new BusUser();
		user.forMember(unifiedUser);
		user.setAttr(attr);
		if(uncheck){
			user.setStatu(BusUser.USER_STATU_CHECKING);
		}else{
			user.setStatu(BusUser.USER_STATU_CHECKED);
		}
		user.init();
		entityDao.save(user);
		busUserExtMng.save(userExt, user);
		return user;
	}

	
	public BusUser registerMember(String username, String email,
			String password, String ip, Integer groupId, boolean uncheck,BusUserExt userExt,Map<String,String>attr,
			Boolean activation, EmailSender sender, MessageTemplate msgTpl)throws UnsupportedEncodingException, MessagingException{
		UnifiedUser unifiedUser = unifiedUserMng.save(username, email,
				password, ip, activation, sender, msgTpl);
		BusUser user = new BusUser();
		user.forMember(unifiedUser);
		user.setAttr(attr);
		if(uncheck){
			user.setStatu(BusUser.USER_STATU_CHECKING);
		}else{
			user.setStatu(BusUser.USER_STATU_CHECKED);
		}
		user.init();
		entityDao.save(user);
		busUserExtMng.save(userExt, user);
		return user;
	}

	public void updateLoginInfo(Integer userId, String ip,Date loginTime,String sessionId) {
		BusUser user = findById(userId);
		if (user != null) {
			user.setLoginCount(user.getLoginCount() + 1);
			if(StringUtils.isNotBlank(ip)){
				user.setLastLoginIp(ip);
			}
			if(loginTime!=null){
				user.setLastLoginTime(loginTime);
			}
			user.setSessionId(sessionId);
		}
	}

	public void updateUploadSize(Integer userId, Integer size) {
		BusUser user = findById(userId);
		user.setUploadTotal(user.getUploadTotal() + size);
		if (user.getUploadDate() != null) {
			if (BusUser.isToday(user.getUploadDate())) {
				size += user.getUploadSize();
			}
		}
		user.setUploadDate(new java.sql.Date(System.currentTimeMillis()));
		user.setUploadSize(size);
	}
	
	public boolean isPasswordValid(Integer id, String password) {
		return unifiedUserMng.isPasswordValid(id, password);
	}

	public void updatePwdEmail(Integer id, String password, String email) {
		BusUser user = findById(id);
		if (!StringUtils.isBlank(email)) {
			user.setEmail(email);
		} else {
			user.setEmail(null);
		}
		unifiedUserMng.update(id, password, email);
	}

	public BusUser saveAdmin(String username, String email, String password,
			String ip, boolean viewOnly, boolean selfAdmin, int rank,
			Integer groupId,Integer[] roleIds, Integer[] channelIds,Integer[] siteIds,
			Byte[] steps, Boolean[] allChannels, BusUserExt userExt) {
		UnifiedUser unifiedUser = unifiedUserMng.save(username, email,
				password, ip);
		BusUser user = new BusUser();
		user.forAdmin(unifiedUser, viewOnly, selfAdmin, rank);
		/*
		if (department == null) {
			throw new RuntimeException(
					"register default admin department not setted!");
		}
		*/
		user.init();
		entityDao.save(user);
		busUserExtMng.save(userExt, user);
		return user;
	}


	public BusUser updateMember(Integer id, String email, String password,
			Boolean isDisabled, BusUserExt ext, Integer groupId,Integer grain,Map<String,String>attr) {
		BusUser entity = findById(id);
		entity.setEmail(email);
		/*
		if (!StringUtils.isBlank(email)) {
			entity.setEmail(email);
		}
		*/
		if (isDisabled != null) {
			if(isDisabled){
				entity.setStatu(BusUser.USER_STATU_DISABLED);
			}else{
				entity.setStatu(BusUser.USER_STATU_CHECKED);
			}
		}
		// 更新属性表
		if (attr != null) {
			Map<String, String> attrOrig = entity.getAttr();
			attrOrig.clear();
			attrOrig.putAll(attr);
		}
		busUserExtMng.update(ext, entity);
		unifiedUserMng.update(id, password, email);
		return entity;
	}
	
	public BusUser updateMember(Integer id, String email, String password,Integer groupId,String realname,String mobile,Boolean sex) {
		BusUser entity = findById(id);
		BusUserExt ext =entity.getUserExt();
		if (!StringUtils.isBlank(email)) {
			entity.setEmail(email);
		}
		if (!StringUtils.isBlank(realname)) {
			ext.setRealname(realname);
		}
		if (!StringUtils.isBlank(mobile)) {
			ext.setMobile(mobile);
		}
		if (sex!=null) {
			ext.setGender(sex);
		}
		busUserExtMng.update(ext, entity);
		unifiedUserMng.update(id, password, email);
		return entity;
	}
	
	public BusUser deleteById(Integer id) {
		unifiedUserMng.deleteById(id);
		BusUser bean = entityDao.deleteById(id);
		return bean;
	}

	public BusUser[] deleteByIds(Integer[] ids) {
		BusUser[] beans = new BusUser[ids.length];
		for (int i = 0, len = ids.length; i < len; i++) {
			
			beans[i] = deleteById(ids[i]);
		}
		return beans;
	}

	public boolean usernameNotExist(String username) {
		return entityDao.countByUsername(username) <= 0;
	}
	
	public boolean usernameNotExistInMember(String username){
		return entityDao.countMemberByUsername(username)<= 0;
	}

	public boolean emailNotExist(String email) {
		return entityDao.countByEmail(email) <= 0;
	}

	private BusUserSiteMng busUserSiteMng;
	private UnifiedUserMng unifiedUserMng;
	private BusUserExtMng busUserExtMng;
	private BusUserEntityDao entityDao;
	private BusUserDao dao;
	

	@Autowired
	public void setBusUserSiteMng(BusUserSiteMng busUserSiteMng) {
		this.busUserSiteMng = busUserSiteMng;
	}

	@Autowired
	public void setUnifiedUserMng(UnifiedUserMng unifiedUserMng) {
		this.unifiedUserMng = unifiedUserMng;
	}

	@Autowired
	public void setBusUserExtMng(BusUserExtMng busUserExtMng) {
		this.busUserExtMng = busUserExtMng;
	}

	@Autowired
	public void setentityDao(BusUserEntityDao entityDao) {
		this.entityDao = entityDao;
	}

	@Autowired
	public void setDao(BusUserDao dao) {
		this.dao = dao;
	}

}